package com.bangdao.threadpool;

/**
 * @author chen
 * @create 2021-01-06
 */

import java.util.concurrent.*;

/**
 * **线程池的优势：
 * 线程池做的工作主要是:控制运行的线程数量，处理过程中将任务放入队列，然后在线程创建后启动这些任务，
 * 如果线程数量超过了最大数量，超出数量的线程排队等候，等其他线程执行完毕，再从队列中取出任务来执行。**
 * <p>
 * 它的主要特点为：线程复用；控制最大并发数；管理线程。
 * <p>
 * 1.通过Executors工具类实现
 * Executors.newSingleThreadExecutor()   开启一个线程，最大阻塞队列
 * Executors.newFixedThreadPool()   	固定线程池，最大阻塞队列
 * Executors.newScheduledThreadPool()  定时任务线程池，最大线程数是最大整型
 * Executors.newCachedThreadPool()	    最大线程数是最大整型
 * <p>
 * 2.通过自定义线程池
 * new ThreadPoolExecutor(
 * 有七大参数：1.核心线程数 2.最大线程数 3.最大存活时间 4.存活时间的单位 5.阻塞队列 6.默认工厂
 * 7.拒绝策略
 * 拒绝策略又分为4中：
 * AbortPolicy: 默认  会抛异常
 * CalledrunsPolicy: 调用者 处理不了的请求会交由调用者处理
 * DiscardOldestPolicy: 抛弃等待最长的任务，重新加入任务
 * DiscardPolicy: 默默抛弃一个任务
 * )
 * 执行流程：
 * 创建线程池，初始线程数为0；当任务请求到达线程池，首先判断核心线程数是否已满，未满创建核心线程处理任务，
 * 已满判断队列是否已满，未满将任务添加到队列中去，已满判断最大线程数是否已满，未满则开启普通线程处理任务，
 * 已满则执行拒绝策略。当任务全部处理完，也没有请求过来，判断是否超过核心线程数和存活时间，销毁线程，
 * 我们也可以通过自定义策略记录拒绝请求
 */
public class ThreadPoolDemo {
    public static void main(String[] args) {
        //最大线程数是最大整型
//        ExecutorService threadPool = Executors.newCachedThreadPool();
        // 创建单一线程的连接池
//         ExecutorService threadPool = Executors.newSingleThreadExecutor();
        //固定线程池，最大阻塞队列
//         ExecutorService threadPool = Executors.newFixedThreadPool(3);
        // 自定义连接池
        ExecutorService threadPool = new ThreadPoolExecutor(2, 5,
                2, TimeUnit.SECONDS, new ArrayBlockingQueue<>(3),
                Executors.defaultThreadFactory(),
                //new ThreadPoolExecutor.AbortPolicy()
                //new ThreadPoolExecutor.CallerRunsPolicy()
                //new ThreadPoolExecutor.DiscardOldestPolicy()
                //new ThreadPoolExecutor.DiscardPolicy()
                new RejectedExecutionHandler() {
                    @Override
                    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                        System.out.println("自定义拒绝策略");
                    }
                }
        );
        try {
            for (int i = 0; i < 9; i++) {
                threadPool.execute(() -> {
                    System.out.println(Thread.currentThread().getName() + "执行了业务逻辑");
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //将线程放回线程池
            threadPool.shutdown();
        }
    }
}
